﻿/**
 * XmlLoader Class
 * Copyright (c) 2009 designmarco
 * @author Marco Di Giuseppe  |  http://designmarco.com
 * marco[at]designmarco[dot]com
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package com.designmarco.loaders
{
	import com.designmarco.events.XmlLoaderEvent;
	import flash.events.IEventDispatcher;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.Event;
	import flash.net.URLRequest;
	import flash.net.URLLoader;
	/**
	 * XmlLoader handles the loading of an external XML file
	 * which can be accessed directly through its complete event.
	 * @example
	 * <code>
		import com.designmarco.loaders.XmlLoader; <br/>
		import com.designmarco.events.XmlLoaderEvent; <br/> <br/>
						
		var xmlLoader:XmlLoader = new XmlLoader("data.xml"); <br/>
		xmlLoader.addEventListener(XmlLoaderEvent.COMPLETE, onXmlLoaded); <br/><br/>
						
		function onXmlLoaded(event:XmlLoaderEvent):void<br/>
		{
			var xml:XML = XML(event.xml); <br/>
			trace(xml);<br/>
		}
		</code>
	 */
	public class XmlLoader extends EventDispatcher
	{
		/**
		 * Load XML passed in the Constructor
		 * @param	url		path to xml file
		 */
		public function XmlLoader(url:String = "")
		{
			var request:URLRequest = new URLRequest(url);
			if (request)
			{
				var loader:URLLoader = new URLLoader();
				configureListeners(loader, true);
				loader.load(request);
			}
			else
				dispatchEvent(new XmlLoaderEvent(XmlLoaderEvent.ERROR));
		}

		/**
		 * Listen for XML to complete loading
		 * @param	event	Event.COMPLETE
		 */
		private function completeHandler(event:Event):void
		{
			var loader:URLLoader = URLLoader(event.target);
			dispatchEvent(new XmlLoaderEvent(XmlLoaderEvent.COMPLETE, new XML(loader.data)));
			configureListeners(loader, false);
		}

		/**
		 * Listen for possible loading errors
		 * @param	event	IOErrorEvent
		 */
		private function ioErrorHandler(event:IOErrorEvent):void
		{
			dispatchEvent(new XmlLoaderEvent(XmlLoaderEvent.ERROR));
		}

		/**
		 * Mangage the event listeners that will handle the loading notifications
		 * @param	dispatcher	dispatches event
		 * @param   b			true to addEventListener , false to removeEventListener
		 */
		private function configureListeners(dispatcher:IEventDispatcher, b:Boolean):void
		{
			var action:String = (b) ? "addEventListener" : "removeEventListener";
			dispatcher[action](Event.COMPLETE, completeHandler);
			dispatcher[action](IOErrorEvent.IO_ERROR, ioErrorHandler);
		}
	}
}